package me.zhengjie.modules.weChat.rest;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.annotation.AnonymousAccess;
import me.zhengjie.annotation.Log;

import me.zhengjie.modules.security.config.SecurityProperties;
import me.zhengjie.modules.security.security.TokenProvider;
import me.zhengjie.modules.security.service.OnlineUserService;
import me.zhengjie.modules.security.service.dto.AuthUserDto;
import me.zhengjie.modules.security.service.dto.JwtUserDto;
import me.zhengjie.modules.system.service.UserService;
import me.zhengjie.modules.weChat.config.SystemConfig;
import me.zhengjie.modules.weChat.domain.SysWechatUser;
import me.zhengjie.modules.weChat.domain.vo.WeChatVo;
import me.zhengjie.modules.weChat.service.SysWechatUserService;
import me.zhengjie.modules.weChat.service.WXService;
import me.zhengjie.modules.weChat.service.dto.UserWeChat;
import me.zhengjie.modules.weChat.utils.WechatUtil;
import me.zhengjie.modules.weChat.utils.WxUtil;
import me.zhengjie.utils.RedisUtils;
import me.zhengjie.utils.RestResponse;
import me.zhengjie.utils.SecurityUtils;

import me.zhengjie.utils.UniqueOrderGenerate;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Zheng Jie
 * @date 2018-11-23
 * 授权、根据token获取用户详细信息
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/wx/student/auth")
@Api(tags = "微信：微信授权接口")
public class WXauthController {

    private final SecurityProperties properties;

    @Value("${single.login:false}")
    private Boolean singleLogin;


    private final SystemConfig systemConfig;
    private final UserService userService;
    private final AuthenticationManagerBuilder authenticationManagerBuilder;
    private final TokenProvider tokenProvider;
    private final OnlineUserService onlineUserService;
    private final UserDetailsService userDetailsService;
    private final WXService wxService;
    private final SysWechatUserService sysWechatUserService;

    @Log("用户登录")
    @ApiOperation("登录授权")
    @AnonymousAccess
    @PostMapping(value = "/login")
    public RestResponse login(AuthUserDto authUser, HttpServletRequest request){

        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(authUser.getUsername(), authUser.getPassword());

        Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
        SecurityContextHolder.getContext().setAuthentication(authentication);

        // 生成令牌
        String token = tokenProvider.createToken(authentication);
        final JwtUserDto jwtUser = (JwtUserDto) authentication.getPrincipal();
        // 保存在线信息
        onlineUserService.save(jwtUser, token, request);
        // 返回 token 与 用户信息
        Map<String,Object> authInfo = new HashMap<String,Object>(2){{
            put("token", properties.getTokenStartWith() + token);
            put("user", jwtUser);
        }};

        String code = authUser.getCode();
        String openid = WxUtil.getOpenId(systemConfig.getWx().getAppid(), systemConfig.getWx().getSecret(), code);
        if (null == openid) {
            return RestResponse.fail(4, "获取微信OpenId失败");
        }

        authInfo.put("openid",openid);
        wxService.saveOpenIdToken(properties.getTokenStartWith() + token,openid);

        if(singleLogin){
            System.out.println("踢掉之前已经登录的token");
            //踢掉之前已经登录的token
            onlineUserService.checkLoginOnUser(authUser.getUsername(),token);
        }
        return RestResponse.ok(authInfo);
    }

    @Log("微信用户登录")
    @ApiOperation("微信登录授权")
    @AnonymousAccess
    @PostMapping(value = "/wxLogin")
    @ResponseBody
    public RestResponse wxLogin(WeChatVo weChatVo,HttpServletRequest request) throws Exception {
        Map<String, Object> stringObjectMap = sysWechatUserService.wxLogin(weChatVo, request);
        RestResponse result;
        if (stringObjectMap==null){
            result= RestResponse.fail(500,"签名校验失败");
        }else{
            result= RestResponse.ok(stringObjectMap);
        }

        return result;
    }



    @ApiOperation("获取用户信息")
    @PostMapping(value = "/info")
    public RestResponse<Map<String, Object>> getUserInfo(){
        JwtUserDto jwtUser = (JwtUserDto)userDetailsService.loadUserByUsername(SecurityUtils.getCurrentUsername());
        System.out.println(jwtUser);
        Map<String,Object> user = new HashMap<String,Object>();
        user.put("userName",jwtUser.getUsername());
        user.put("realName",jwtUser.getUsername());
        user.put("imagePath","http://image.chenzhenming.top/upload/20190818/bff385329a584d749135448f01547fa6.jpg");
        return RestResponse.ok(user);
    }

    @AnonymousAccess
    @RequestMapping(value = "/checkBind", method = RequestMethod.POST)
    public RestResponse checkBind(@Valid @NotBlank String code) {
        String token = sysWechatUserService.checkBind(code);
        if (null != token) {
            return RestResponse.ok(token);
        }
        return RestResponse.fail(2, "用户未绑定");
    }

    @ApiOperation("退出登录")
    @AnonymousAccess
    @DeleteMapping(value = "/logout")
    public ResponseEntity<Object> logout(HttpServletRequest request){
        onlineUserService.logout(tokenProvider.getToken(request));
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @AnonymousAccess
    @GetMapping(value = "/ming")
    public RestResponse test(HttpServletRequest request) throws Exception {
        String o = "oLqXz5Ao0kkhmgTvYMyWV5YZThAM";
        UserWeChat userByOpenId = sysWechatUserService.findUserByOpenId(o);

        return RestResponse.ok(userByOpenId);
    }
    @GetMapping(value = "/addy")
    public RestResponse addy(HttpServletRequest request) throws Exception {

        return RestResponse.ok("authInfo");
    }
}
